<?php

namespace app\common\service;
use app\common\model\WalletReserveUsdtModel;
use app\common\model\WalletReserveEthModel;
use app\common\service\CalcService;
use app\common\service\BalanceService;
use think\Db;

/*
钱包管理
1.生成币种地址
2.刷新区块数据
 */
class WalletService{
	
	//生成币种地址
	public static function createAddress($uid,$coin){
		$res = 1;

		//是否有该系列地址
		$has_address = Db::table('tp_user_wallet_address')->where('coin_type',$coin['coin_type'])->where('uid',$uid)->find();
		$data = [
				'wid'=>$coin['wid'],
				'cid'=>$coin['id'],
				'uid'=>$uid,
				'coin_type'=>$coin['coin_type'],
				'block'=>0,
			];
		if ($has_address) {
			$data['address'] = $has_address['address'];
			
		} else {
			Db::startTrans();
			switch ($coin['coin_type']) {
				//以太坊系列
				case 1:
					$url = '';
					// $url = 'http:///api/eth/getAddress?ssr=1&pass='.$uid;
					if (!$url) {
						$data['address'] = '0x'.$uid.'123456789';
					} else {
						try{
						 //   	ini_set('default_socket_timeout',3);//三秒超时
							// $address = curl($url);
							// $address = json_decode($address,1);
							// if ($address['code'] == 0) {
							// 	$data['address'] = $address['msg'];
							// } else {
								$address = Db::table('tp_wallet_address_list')->where('uid',0)->where('type',$coin['coin_type'])->find();
								if ($address) {
									$data['address'] = $address['address'];
									$res1 = Db::table('tp_wallet_address_list')->where('id',$address['id'])->update(['uid'=>$uid]);
								} else {
									// ini_set('default_socket_timeout',3);//三秒超时
									$address = curl($url);
									$address = json_decode($address,1);

									if ($address['code'] == 0) {
										$data['address'] = $address['data'];
									}
								} 
						} catch (\Exception $e) {
							Db::rollback();
						   	return false;
						}
					}
					break;
				//比特币系列，泰达币系列
				case 2:
					$url = '';
					if (!$url) {
						$data['address'] = 'btc'.$uid.'123456789';
					} else {
						$address = curl($url);
						$data['address'] = $address['address'];
					}
					break;
				//EOS系列
				case 3:
					$url = '';
					if (!$url) {
						$data['address'] = 'eos'.$uid.'123456789';
					} else {
						$address = curl($url);
						$data['address'] = $address['address'];
					}
					break;
				//TRC系列
				case 4:
					// $url = '';
					$url = 'http://154.39.150.28/api/trx/getAddress?ssr=1&pass='.$uid;

					if (!$url) {
						$data['address'] = 'trc'.$uid.'123456789';
					} else {
						try{
						 //   	ini_set('default_socket_timeout',3);//三秒超时
							// $address = curl($url);
							// $address = json_decode($address,1);
							// if ($address['code'] == 0) {
							// 	$data['address'] = $address['msg'];
							// } else {
								$address = Db::table('tp_wallet_address_list')->where('uid',0)->where('type',$coin['coin_type'])->find();
								if ($address) {
									$data['address'] = $address['address'];
									$res1 = Db::table('tp_wallet_address_list')->where('id',$address['id'])->update(['uid'=>$uid]);
								} else {
									// ini_set('default_socket_timeout',3);//三秒超时
									$address = curl($url);
									$address = json_decode($address,1);

									if ($address['code'] == 0) {
										$data['address'] = $address['data']['address'];
									}
								} 

						} catch (\Exception $e) {
							Db::rollback();
						    return false;
						}
					}
					break;
				//dash系列
				case 5:
					$url = '';
					if (!$url) {
						$data['address'] = 'dash'.$uid.'123456789';
					} else {
						$address = curl($url);
						$data['address'] = $address['address'];
					}
					break;
				case 6:
					$url = '';
					break;
				case 7:
					$url = '';
					break;
				case 8:
					$url = '';
					break;
				case 9:
					$url = '';
					break;
				//系统币
				case 10:
					// $data['address'] = $coin['name'].md5($uid.microtime()).substr(md5(microtime()),0,5);
					$data['address'] = md5($uid.microtime()).substr(md5(microtime()),0,5);
					break;
				default:
					# code...
					break;
			}
		}
		$res = model('WalletAddressModel')->addData($data);
		if($res){
			Db::commit();
			return $data['address'];
		} else {
			Db::rollback();
			return false;
		}	
	}


	//刷新区块数据
	public static function reQk($uid,$coin){
		$res = 1;
		//ETH
		if($coin['name'] == 'ETH' && $coin['coin_type']==1){
			$res = self::eth($uid,$coin);
		}
		//ETH代币
		if($coin['coin_type'] == 1 && $coin['contract_address']){
			$res = self::ceth($uid,$coin,$coin['contract_address']);
		}
		//BTC
		if($coin['name'] == 'BTC' && $coin['coin_type']==2){
			$res = self::btc($uid,$coin);
		}
		//OMNI
		if($coin['name'] == 'OMNI' && $coin['coin_type']==2){
			$res = self::omni($uid,$coin);
		}
		//EOS
		if($coin['name'] == 'EOS' && $coin['coin_type']==3){
			//充值地址
			$res = self::eos($uid,$coin,$coin['recharge_address']);
		}
		//TRC
		if($coin['coin_type']==4){
			// var_dump($coin['name']);
			$res = self::trc($uid,$coin,$coin['contract_address']);
		}
		//DASH
		if($coin['name'] == 'DASH' && $coin['coin_type']==5){
			$res = self::dash($uid,$coin);
		}
		return $res;
	}

	//以太坊
	public static function eth($uid,$coin){
		$cid = $coin['id'];
		$eth = Db::table('tp_user_wallet_address')->where('uid',$uid)->where('cid',$cid)->order('id asc')->find();
		if(!$eth){
			return false;
		}
		$address = $eth['address'];
		$block   = $eth['block'];
		$ret = curl('https://api.etherscan.io/api?module=account&action=txlist&startblock='.$block.'&address='.$address.'&apikey=YourApiKeyToken');
		$arr = json_decode($ret, 1);
		if ($arr['status']==0){
			return true;
		} else {
			Db::startTrans();
			$data = $arr['result'];
			$max_block = $block;
			
			$eth_price = C('eth_price');
			foreach ($data as $key => $val) {
				if(strtolower($val['to']) == strtolower($address)){
					if($val['blockNumber']>$block){
						$balance = $val['value']/1000000000000000000;

						$balance = $balance*$eth_price;

						$res = BalanceService::updateBalance($uid, $coin['wid'] , $balance, '外网转入',12,0,$val['from']);
						if(!$res){
							Db::rollback();
							return false;
						}
					}
					if($val['blockNumber']>$max_block){
						$max_block = $val['blockNumber'];
					}
				}	
			}
			if($max_block == $block){
				$res = 1;
			} else {
				$res = model('WalletAddressModel')->updateBlock($uid,$cid,$max_block);
			}
			if($res){
				Db::commit();
				return true;
			} else {
				Db::rollback();
				return false;
			}
		}
	}

	//trc20
	public static function trc($uid,$coin,$contract_address){
		$cid = $coin['id'];
		$ceth = Db::table('tp_user_wallet_address')->where('uid',$uid)->where('cid',$cid)->order('id asc')->find();
		if(!$ceth){
			return false;
		}
		$fm      = 1000000;
		$address = $ceth['address'];
		$block   = $ceth['block'];
		$ret = curl("https://api.trongrid.io/v1/accounts/".$address."/transactions/trc20?only_confirmed=true&limit=200&contract_address=".$contract_address."&order_by=block_timestamp,desc");

		$arr = json_decode($ret, 1);

		
		if (!$arr['success']){
			return true;
		} else {
			Db::startTrans();
			$data  = $arr['data'];
			if (empty($data)) {
				Db::rollback();
				return true;
			}
			$max_block = $block;
			foreach ($data as $key => $val) {
				if(strtolower($val['to']) == strtolower($address)){
					if($val['block_timestamp']>$block){
						$balance = $val['value']/$fm;
						$res = BalanceService::updateBalance($uid, $coin['wid'] , $balance, '外网转入',12,0,$val['from']);
						if(!$res){
							Db::rollback();
							return false;
						}
					}
					if($val['block_timestamp']>$max_block){
						$max_block = $val['block_timestamp'];
					}
				}	
			}
			if($max_block == $block){
				$res = 1;
			} else {
				$res = model('WalletAddressModel')->updateBlock($uid,$cid,$max_block);
			}
			if($res){
				Db::commit();
				curl('http://154.39.150.28/api/trx/sendSpeed?address='.$address);
				return true;
			} else {
				Db::rollback();
				return false;
			}
		}
	}




	//以太坊代币
	public static function ceth($uid,$coin,$contract_address){
		$cid  = $coin['id'];
		$ceth = Db::table('tp_user_wallet_address')->where('uid',$uid)->where('cid',$cid)->order('id asc')->find();
		// var_dump($ceth);die();
		if(!$ceth){
			return false;
		}
		switch ($cid) {
			case 8:
				$fm = 1000000;
				break;
			// case 7:
			// 	$fm = 100000000;
			// 	break;
			default:
				$fm = 1000000;
				break;
		}
		$address = $ceth['address'];
		$block   = $ceth['block'];
		$ret = curl('https://api-cn.etherscan.io/api?module=account&action=tokentx&startblock='.$block.'&address='.$address.'&contractaddress='.$contract_address.'&apikey=D1XFTT7JYI9NMBCI3KGJH9SKVWWIGN34B2');
		$arr = json_decode($ret, 1);
		if ($arr['status']==0){
			return true;
		} else {
			Db::startTrans();
			$data  = $arr['result'];
			$max_block = $block;
			foreach ($data as $key => $val) {
				if(strtolower($val['to']) == strtolower($address)){
					if($val['blockNumber']>$block){
						$balance = $val['value']/$fm;
						$res = BalanceService::updateBalance($uid, $coin['wid'] , $balance, '外网转入',12,0,$val['from']);
						if(!$res){
							Db::rollback();
							return false;
						}
					}
					if($val['blockNumber']>$max_block){
						$max_block = $val['blockNumber'];
					}
				}	
			}
			if($max_block == $block){
				$res = 1;
			} else {
				$res = model('WalletAddressModel')->updateBlock($uid,$cid,$max_block);
			}
			if($res){
				Db::commit();
				return true;
			} else {
				Db::rollback();
				return false;
			}
		}
	}

	
	//BTC
	// public static function btc($uid,$cid){
	// 	$btc = Db::table('tp_user_wallet_address')->where('uid',$uid)->where('cid',$cid)->order('id desc')->find();
	// 	if(!$btc){
	// 		return false;
	// 	}
	// 	$address = $btc['address'];
	// 	$block   = $btc['block'];
	// 	//是否有新交易
	// 	$total_count = $btc['total_count'];
	// 	$ret = curl('http://wotrack.com:8008/btc/tx?address='.$address);

	// 	$arr = json_decode($ret, 1);
	// 	if ($arr['n_tx']==0){
	// 		return true;
	// 	} else {
	// 		//无新交易
	// 		if($total_count >= $arr['n_tx']){
	// 			return true;
	// 		} else {
	// 			$total_count = $arr['n_tx'];
	// 		}
	// 		Db::startTrans();
	// 		$data      = $arr['txs'];
	// 		$max_block = $block;
	// 		foreach ($data as $key => $val) {
	// 			//转入
	// 			// if($val['ver'] == 1){
	// 			if($val['block_height']>$block){
	// 				$status = 1;
	// 				foreach ($val['inputs'] as $k => $v) {
	// 					if(isset($v['prev_out']['addr'])){
	// 						if($v['prev_out']['addr'] == $address){
	// 							$status = 0;
	// 							break;
	// 						}
	// 					}
	// 				}
	// 				if($status == 1){
	// 					$from = $val['inputs'][0]['prev_out']['addr'];
	// 					$balance = 0;
	// 					foreach ($val['out'] as $k => $v) {
	// 						if(isset($v['addr'])){
	// 							if($v['addr'] == $address){
	// 								$balance += $v['value']/100000000;
	// 							}
	// 						}
	// 					}
	// 					$res = BalanceService::updateBalance($uid, $coin['wid'] , $balance, '外网转入',12,0,$from);
	// 					if(!$res){
	// 						Db::rollback();
	// 						return false;
	// 					}
	// 					if($val['block_height']>$max_block){
	// 						$max_block = $val['block_height'];
	// 					}
	// 				}	
	// 			}
	// 			// }
	// 		}
	// 		if($max_block == $block){
	// 			$res = 1;
	// 		} else {
	// 			$res = model('WalletAddressModel')->updateBlock($uid,$cid,$max_block,$total_count);
	// 		}
	// 		if($res){
	// 			Db::commit();
	// 			return true;
	// 		} else {
	// 			Db::rollback();
	// 			return false;
	// 		}
	// 	}
	// }
	//BTC
	public static function btc($uid,$coin){
		$cid = $coin['id'];
		$btc = Db::table('tp_user_wallet_address')->where('uid',$uid)->where('cid',$cid)->order('id asc')->find();
		if(!$btc){
			return false;
		}
		$address = $btc['address'];
		$block   = $btc['block'];
		$total_count = $btc['total_count'];
		$ret = curl('https://chain.api.btc.com/v3/address/'.$address.'/tx');
		$arr = json_decode($ret, 1);
		if ($arr['err_no']!=0){
			return true;
		} else {
			//无新交易
			if($total_count == $arr['data']['total_count']){
				return true;
			}
			Db::startTrans();
			$data  = $arr['data']['list'];
			$max_block = $block;
			foreach ($data as $key => $val) {
				if($val['to'] == $address){
					if($val['block_height']>$block){
						$balance = $val['value']/100000000;
						$res = BalanceService::updateBalance($uid, $coin['wid'] , $balance, '外网转入',12,0,$val['from']);
						if(!$res){
							Db::rollback();
							return false;
						}
					}
					if($val['block_height']>$max_block){
						$max_block = $val['block_height'];
					}
				}	
			}
			if($max_block == $block){
				$res = 1;
			} else {
				$res = model('WalletAddressModel')->updateBlock($uid,$cid,$max_block,$total_count);
			}
			if($res){
				Db::commit();
				return true;
			} else {
				Db::rollback();
				return false;
			}
		}
	}
 

	//EOS
	public static function eos($uid,$coin,$into_address){
		$cid = $coin['id'];
		if(!$into_address){
			return true;
		}
		$eos = Db::table('tp_user_wallet_address')->where('uid',$uid)->where('cid',$cid)->order('id asc')->find();
		if(!$eos){
			return false;
		}
		$memo  = $eos['address'];
		$block = $eos['block'];
		$ret = curl('http://wotrack.com:8008/eos/tx?address='.$into_address);
		$arr = json_decode($ret, 1);
		if (empty($arr['actions'])){
			return true;
		} else {
			Db::startTrans();
			$data      = $arr['actions'];
			$max_block = $block;
			foreach ($data as $key => $val) {
				//转入
				if($val['block_num']>$block){
					$info = $val['action_trace']['act']['data'];
					if(!isset($info['from'])){
						continue;
					}
					if(!isset($info['to'])){
						continue;
					}
					if(!isset($info['quantity'])){
						continue;
					}
					if(!isset($info['memo'])){
						continue;
					}
					$quantity = explode(" ", $info['quantity']);
					if($quantity[1] != 'EOS'){
						continue;
					}
					if($info['to'] != $into_address){
						continue;
					}
					if($info['memo'] != $memo){
						continue;
					}
					$from = $info['from'];
					$balance = $quantity[0];
					$res = BalanceService::updateBalance($uid, $coin['wid'] , $balance, '外网转入',12,0,$from);
					if(!$res){
						Db::rollback();
						return false;
					}
					if($val['block_num']>$max_block){
						$max_block = $val['block_num'];
					}
				}
			}
			if($max_block == $block){
				$res = 1;
			} else {
				$res = model('WalletAddressModel')->updateBlock($uid,$cid,$max_block);
			}
			if($res){
				Db::commit();
				return true;
			} else {
				Db::rollback();
				return false;
			}
		}
	}



	public static function omni($uid,$coin){
		$cid = $coin['id'];
		//USDT
		$usdt = Db::table('tp_user_wallet_address')->where('uid',$uid)->where('cid',$cid)->order('id asc')->find();
		if(!$usdt){
			return false;
		}
		$address = $usdt['address'];
		$post_data = ['addr'=>$address];
		$header = ['Content-Type: application/x-www-form-urlencoded'];
		
		$res = curl('https://api.omniexplorer.info/v1/transaction/address',$post_data,'post',$header);
		$res = json_decode($res,1);
		if(!$res['transactions']){
			return true;
		}
		$now_block = $usdt['block'];
		$max_block = $now_block;
		Db::startTrans();
		for ($i=$res['pages']; $i >0 ; $i--) { 
			$post_data = ['addr'=>$address,'page'=>$i];
			$res = curl('https://api.omniexplorer.info/v1/transaction/address',$post_data,'post',$header);
			$res = json_decode($res,1);
			$trade_list = $res['transactions'];
			// $block = array_column($trade_list,'block');
			// array_multisort($block,SORT_ASC,$trade_list);
			foreach ($trade_list as $key => $val) {
				if ($val['propertyname'] != 'TetherUS') {
					continue;
				} 
				if($val['block'] <= $now_block){
					continue;
				}
				if($val['referenceaddress'] != $address){
					continue;
				}
				if($val['block'] > $max_block){
					$max_block = $val['block'];
				}
				$res = BalanceService::updateBalance($uid, $coin['wid'] , $val['amount'], '外网转入',12,0,$val['sendingaddress']);
				if(!$res){
					Db::rollback();
					return false;
				}
			}
		}
		if($max_block == $now_block){
			$res = 1;
		} else {
			$res = model('WalletAddressModel')->updateBlock($uid,$cid,$max_block);
		}
		if($res){
			Db::commit();
			return true;
		} else {
			Db::rollback();
			return false;
		}
	}
}
